home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / Pascal / Code Resources / Eclectic CDEFs / Celsius CDEF Folder / CalculateBarBoundary Folder / CalculateBarBoundary.c next >
C/C++ Source or Header  |  1997-02-28  |  3KB  |  73 lines

  1. #include <Types.h>
  2. #include <Controls.h>
  3.  
  4.  
  5. /*
  6.     CalculateBarBoundary
  7.     
  8.     Calculates the right edge of the 'done' part of the progress bar, given the bar's edges
  9.     and the control handle. This method works if the following conditions hold:
  10.         (1) inControlBoxRight >= inControlBoxLeft, and
  11.         (2) contrlMax >= contrlValue >= contrlMin.
  12.     Both of these should be met in normal circumstances. If these restrictions hold, then the
  13.     differences (both in the numerator and the one in the denominator) will fit into 16-bit unsigned
  14.     integers. That means that we can use the mulu.w and divu.w instructions to perform the multiply
  15.     and divide, instead of requiring the addition of the software library for 32 bit multiplication
  16.     on the 68000.
  17.     The only other thing to note is that a division by zero can’t happen. The denominator is zero
  18.     only when contrlMax == contrlMin. If this is the case, then contrlValue == contrlMin and the
  19.     branch before the multiply will be taken, so the division instruction is never reached.
  20.     
  21.     Entry:    inControlHdl = handle to control
  22.             inControlBoxLeft = left edge of the control's box
  23.             inControlBoxRight = right edge of the control's box
  24.     Exit:    function result = right edge of the 'done' part of the progress bar
  25.     
  26.     Original versions Copyright © by Chris Larson, Andrew Regan
  27.     Modifications by Sebastiano Pilla
  28.     
  29. */
  30.  
  31. pascal SInt16 CalculateBarBoundary (ControlHandle inControlHdl,
  32.                                     SInt16 inControlBoxLeft,
  33.                                     SInt16 inControlBoxRight)
  34. {
  35.     SInt16    min, max, val, result;
  36.     
  37.     min = (*inControlHdl)->contrlMin;
  38.     max = (*inControlHdl)->contrlMax;
  39.     val = (*inControlHdl)->contrlValue;
  40.     
  41.     asm
  42.     {    
  43.         move.w    inControlBoxRight, D1                    // Right edge of the box to D1
  44.         move.w    inControlBoxLeft, D0                    // Left edge of the box to D0
  45.         sub.w    D0, D1                                    // Width of the box to D1
  46.         
  47.         move.w    val, D2                                    // Control's value to D2
  48.         sub.w    min, D2                                    // Normalized value to D2
  49.         
  50.         beq        @Exit                                    // If normalized value == 0, exit
  51.                                                         // Note that D0 holds the original
  52.                                                         // left edge, which is then picked up
  53.                                                         // and put onto the stack by the compiler
  54.         
  55.         mulu.w    D2, D1                                    // Box width * normalized value to D1
  56.         
  57.         move.w    max, D2                                    // Control's max to D2
  58.         sub.w    min, D2                                    // Normalized maximum to D2
  59.         
  60.         divu.w    D2, D1                                    // Width * value / max to D1
  61.                                                         // Note that division by zero
  62.                                                         // can't happen here
  63.         
  64.         add.w    D1, D0                                    // Offset left edge by amount in D1
  65.                                                         // Place result in D0 for the compiler
  66.         
  67.         @Exit:
  68.         
  69.         move.w    D0, result                                // Return the result
  70.     }
  71.     
  72.     return (result);
  73. }